﻿using System;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.DynamicData;
using System.Web.UI;
using System.Web.UI.WebControls;
using NotAClue.ComponentModel.DataAnnotations;
using NotAClue.Web;
using NotAClue.Web.DynamicData;

namespace DD_Extensions
{
    public partial class ImageUpload_EditField : FieldTemplateUserControl
    {
        private ImageUploadAttribute fileImage;
        private ImageFormatAttribute imageFormat;
        private String primaryKeyValue;
        private String ATTRIBUTE_MISSING_ERROR = "FileImage FieldTemplate for column {0} requires a ImageUploadAttribute";

        public override Control DataControl
        {
            get { return RadioButtonList1; }
        }

        protected void Page_Init(object sender, EventArgs e)
        {
            // add tool-tip
            this.SetupTip();

            // set field options
            this.SetFieldOptions();

            // add CSS from meta data
            this.ApplyCss();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            // get attributes
            fileImage = MetadataAttributes.GetAttribute<ImageUploadAttribute>();
            imageFormat = MetadataAttributes.GetAttribute<ImageFormatAttribute>();
            if (fileImage == null)
                throw new InvalidOperationException("FileUpload must have valid FileUploadAttribute applied");
            else
                FileUploadEdit.ToolTip = String.Format("Upload {0} files", fileImage.FileTypeString());


            // add CustomValidator1's event handler
            CustomValidator1.ServerValidate += new ServerValidateEventHandler(CustomValidator1_ServerValidate);
            RadioButtonList1.DataBound += new EventHandler(RadioButtonList1_DataBound);

            // set validators to use image as error indicator
            this.SetValidatorsToImage();

            // get primary key value
            primaryKeyValue = Table.GetPrimaryKeyValuesAsString(Page);

            if (Column.IsRequired)
            {
                FileUploadEdit.CssClass += " DDRequired";
                RadioButtonList1.CssClass += " DDRequired";
            }
        }

        void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
        {
            // make sure we have an attribute
            if (fileImage == null)
                throw new InvalidOperationException(String.Format(ATTRIBUTE_MISSING_ERROR, Column.Name));

            // don't bother with the validator if in Select mode
            if (fileImage.Editor == EditorType.Select)
                return;

            if (FileUploadEdit.HasFile &&
                !String.IsNullOrEmpty(fileImage.FileUploadPath))
            {
                String fileExtension = FileUploadEdit.FileName.Substring(FileUploadEdit.FileName.LastIndexOf(".") + 1).ToLower();

                if (!fileImage.FileTypes.Contains(fileExtension))
                {
                    // Raise an error if the files extension does not match the allowed extensions
                    args.IsValid = false;
                    CustomValidator1.ErrorMessage = "Not correct Image type, must be one of the following types: " + fileImage.FileTypes.ToString();
                }
            }
            else if (Column.IsRequired && !FileUploadEdit.HasFile && FieldValue == null)
            {
                args.IsValid = false;
                CustomValidator1.ErrorMessage = "No file to upload";
            }
        }

        protected override void OnDataBinding(EventArgs e)
        {
            base.OnDataBinding(e);

            // make sure we have an attribute
            if (fileImage == null)
                throw new InvalidOperationException(String.Format(ATTRIBUTE_MISSING_ERROR, Column.Name));

            var imagesDir = fileImage.FileUploadPath;

            switch (fileImage.Editor)
            {
                case EditorType.Upload:
                    FileUploadEdit.Visible = true;
                    if (FieldValue == null)
                        return;
                    String fileName = (String)FieldValue;
                    ImageEdit.ImageUrl = UploadExtensionMethods.GetUploadPath(imagesDir, Table.Name, primaryKeyValue, Column.Name) + "/" + fileName;

                    if (imageFormat != null)
                    {
                        if (imageFormat.DisplayWidth > 0)
                            ImageEdit.Width = imageFormat.DisplayWidth;
                        if (imageFormat.DisplayHeight > 0)
                            ImageEdit.Height = imageFormat.DisplayHeight;
                    }

                    PlaceHolderImage.Visible = true;
                    break;
                case EditorType.Select:
                default:
                    FileUploadEdit.Visible = false;

                    var dirInfo = new DirectoryInfo(Server.MapPath(imagesDir));
                    if (!dirInfo.Exists)
                        dirInfo.Create(); // if directory does not exist then create it

                    // get a list of images in the ImageUrlAttribute folder
                    var imagesFolder = ResolveUrl(imagesDir);
                    var files = dirInfo.GetFiles();

                    if (imageFormat != null)
                    {
                        // size image to ImageFormatAttribute
                        var imgString = new StringBuilder();

                        foreach (FileInfo file in files)
                        {
                            imgString.Append(
                                String.Format("<img src='{0}' alt='{1}' ",
                                    imagesFolder + file.Name,
                                    file.Name.Substring(0, file.Name.LastIndexOf("."))
                               ));

                            if (imageFormat.DisplayWidth > 0)
                                imgString.Append(String.Format("width='{0}' ", imageFormat.DisplayWidth));

                            if (imageFormat.DisplayHeight > 0)
                                imgString.Append(String.Format("height='{0}' ", imageFormat.DisplayHeight));

                            imgString.Append(" />");

                            // embed image in the radio button
                            var li = new ListItem(imgString.ToString(), file.Name);
                            this.RadioButtonList1.Items.Add(li);
                        }
                    }
                    else
                    {
                        // if no ImageFormatAttribute supplied the do not resize image
                        foreach (FileInfo file in files)
                        {
                            String img = String.Format
                                (
                                    "<img src='{0}' alt='{1}' />",
                                    imagesFolder + file.Name,
                                    file.Name.Substring(0, file.Name.LastIndexOf("."))
                                );
                            // embed image in the radio button
                            var li = new ListItem(img, file.Name);
                            this.RadioButtonList1.Items.Add(li);
                        }
                    }
                    break;
            }
        }

        protected override void ExtractValues(IOrderedDictionary dictionary)
        {
            switch (fileImage.Editor)
            {
                case EditorType.Upload:

                    if (FileUploadEdit.HasFile && !String.IsNullOrEmpty(fileImage.FileUploadPath))
                    {
                        // get the 
                        String imagesDir = UploadExtensionMethods.GetUploadPath(fileImage.FileUploadPath, Table.Name, primaryKeyValue, Column.Name);

                        // resolve full path c:\... etc
                        String path = Server.MapPath(imagesDir);

                        // get files extension without the dot
                        String fileExtension = FileUploadEdit.FileName.Substring(FileUploadEdit.FileName.LastIndexOf(".") + 1).ToLower();

                        if (fileImage.FileTypes.Contains(fileExtension))
                        {
                            // try to upload the file showing error if it fails
                            try
                            {
                                var dirInfo = new DirectoryInfo(path);
                                // make sure folder exists
                                if (!dirInfo.Exists)
                                    dirInfo.Create();

                                // delete files in upload folder
                                if (Mode == DataBoundControlMode.Edit)
                                    dirInfo.DeleteAllFilesInDirectory();

                                FileUploadEdit.PostedFile.SaveAs(path + "\\" + FileUploadEdit.FileName);

                                ImageEdit.ImageUrl = imagesDir + "/" + FileUploadEdit.FileName;
                                ImageEdit.AlternateText = FileUploadEdit.FileName;
                                dictionary[Column.Name] = FileUploadEdit.FileName;
                            }
                            catch (Exception ex)
                            {
                                // display error
                                CustomValidator1.IsValid = false;
                                CustomValidator1.ErrorMessage = ex.Message;
                                dictionary[Column.Name] = null;
                            }
                        }
                    }
                    else
                    {
                        // retrun null if no file or ImageUrlAttribute is null or empty
                        dictionary[Column.Name] = null;
                    }
                    break;
                case EditorType.Select:
                default:
                    // return currently selected item
                    dictionary[Column.Name] = RadioButtonList1.SelectedValue;
                    break;
            }
        }

        protected void RadioButtonList1_DataBound(object sender, EventArgs e)
        {
            if (FieldValue != null && fileImage.Editor == EditorType.Select)
            {
                //var selectedImage = (String)FieldValue;
                RadioButtonList1.Enabled = true;

                for (int i = 0; i < RadioButtonList1.Items.Count; i++)
                {
                    // set select image 
                    if ((String)FieldValue == RadioButtonList1.Items[i].Value)
                    {
                        RadioButtonList1.Items[i].Selected = true;
                        break;
                    }
                }
            }
        }
    }
}